import { delay } from '@material/helpers';
import { MessagePluginManager } from '.';
import { Message, MessageEvent } from '..';
import {
    ChatStatus,
    ErrorType,
    MessageInfo,
    OutputStatus,
    SendApiResult,
    SendParams
} from '../type';
// Todu: 放类里面

interface AiTimeoutPluginOptions {
    timeout: number;
}
export class AiTimeoutPlugin implements MessagePluginManager {
    name: string;
    msgId: string;
    timeout: number;
    stopChatDelay: any;
    startDelyDelay: any;
    isAddTimeout: boolean;
    timeoutDelay: any;
    interrupt: boolean;
    chatStatus: ChatStatus;
    isHasUserInfo: boolean;
    overtimeDelay: any;

    constructor(options?: AiTimeoutPluginOptions) {
        const { timeout = 12 } = { ...options };
        this.name = 'AiTimeoutPlugin';
        this.msgId = '';
        this.timeout = timeout;
        this.stopChatDelay = 0;
        this.overtimeDelay = 0;
        this.isAddTimeout = true;
        this.timeoutDelay = 0;
        this.interrupt = false;
        this.chatStatus = 'ai';
        this.isHasUserInfo = false;
    }
    stopChatNext(context: Message) {
        if (!context) {
            return;
        }
        if (!this.msgId) {
            context.triggerHook(MessageEvent.Error, {
                type: ErrorType.LOGIC,
                message: '为获取到消息ID，无法进行超时拦截'
            });
            return;
        }
        this.interrupt = true;
        context.stopChat(this.msgId);
    }
    clearAllTimeout() {
        this.startDelyDelay?.cancel?.();
        this.stopChatDelay?.cancel?.();
        this.timeoutDelay?.cancel?.();
        this.overtimeDelay?.cancel?.();
    }
    async pushMessage(context: any) {
        this.timeoutDelay = delay(2000);
        await this.timeoutDelay;
        this.doneChat(context);
        this.overtimeDelay = delay(1000);
        await this.overtimeDelay;
        const { isHasUserInfo, msgId } = this;
        context.triggerHook(MessageEvent.Overtime, {
            chatStatus: context.chatStatus,
            outputStatus: !isHasUserInfo ? OutputStatus.InputTimeout : OutputStatus.OutputTimeout,
            messgeId: msgId,
            id: context.autoSumId()
        });
    }

    async overTime(context: any) {
        try {
            this.startDelyDelay = delay(5 * 1000);
            await this.startDelyDelay;
            if (!this.isAddTimeout) {
                return;
            }
            if (!this.isHasUserInfo) {
                this.stopChatNext(context);
                this.isAddTimeout = false;
                this.pushMessage(context);
                return;
            }
            this.stopChatDelay = delay((this.timeout - 7) * 1000);
            await this.stopChatDelay;
            if (!this.isAddTimeout) {
                return;
            }
            this.stopChatNext(context);
            this.pushMessage(context);
        } catch {
            this.clearAllTimeout();
        }
    }
    clearAllStore() {
        this.interrupt = false;
        this.msgId = '';
        this.isAddTimeout = true;
        this.isHasUserInfo = false;
        this.clearAllTimeout();
    }
    doneChat(context: Message) {
        if (!context) {
            return;
        }
        const messageInfo = {
            Content: !this.isHasUserInfo
                ? '抱歉，当前网络出了点问题，请重新发送内容'
                : '抱歉，当前网络出了点问题，暂时无法答复您，请重新发送内容',
            outputType: 'stop',
            From: 'ai',
            FromType: '',
            Event: '',
            chatStatus: context.chatStatus,
            outputStatus: !this.isHasUserInfo
                ? OutputStatus.InputTimeout
                : OutputStatus.OutputTimeout,
            messgeId: this.msgId,
            id: context.autoSumId()
        };
        context.triggerHook(MessageEvent.Message, messageInfo);
        this.clearAllStore();
    }

    startSend(params: SendParams, context: Message) {
        const { chatStatus = 'ai', transformEvent = true } = params;
        this.clearAllStore();
        this.isAddTimeout = !!(chatStatus === 'ai' && transformEvent);
        this.chatStatus = chatStatus;
        if (this.isAddTimeout) {
            this.overTime(context);
        }
        return params;
    }
    afterSend(response: [0 | 1, SendApiResult]) {
        const [err, data] = response;
        if (!err && data && this.isAddTimeout) {
            this.msgId = this.msgId ? this.msgId : data.content || '';
        }
        // Todo: 如果错误直接进入兜底，和产品沟通一下整个
        if (err) {
            this.isHasUserInfo = false;
            this.clearAllStore();
        }

        return response;
    }
    beforeReceive(info: MessageInfo) {
        if (info.FromType === 'user' && info.MsgId) {
            this.isHasUserInfo = true;
            this.msgId = info.MsgId || info.ExtInfo?.msg_id || this.msgId || '';
        }
        if (info && this.interrupt) {
            return false;
        }
        if (info.FromType !== 'user' && this.isAddTimeout) {
            this.isAddTimeout = false;
            this.clearAllTimeout();
        }

        return info;
    }
    beforeDestroy() {
        this.clearAllStore();
    }
}
